using System;

namespace Atomic.Libraries.Physics.Units
{
	[Serializable]
	public abstract class UnitSystem : IUnitSystem
	{
		static UnitSystem()
		{
			AtomicSystem = new AtomicSystemUnitSystem();
			InternationalSystem = new InternationalSystemUnitSystem();
		}

		public abstract double LengthScaling
		{
			get;
		}

		public abstract double TimeScaling
		{
			get;
		}

		public abstract double EnergyScaling
		{
			get;
		}

		public abstract double TemperatureScaling
		{
			get;
		}

		/// <summary>
		/// The unit system used internally in the Atomic library. The base energy unit is eV and the base length unit is Å.
		/// Units in other unit system are defined relative to this system.
		/// </summary>
		public static UnitSystem AtomicSystem
		{
			get;
			private set;
		}

		public static UnitSystem InternationalSystem
		{
			get;
			private set;
		}

		[Serializable]
		private class AtomicSystemUnitSystem : UnitSystem
		{
			public override double LengthScaling
			{
				get
				{
					return 1.0;
				}
			}

			public override double TimeScaling
			{
				get
				{
					return 1.0;
				}
			}

			public override double EnergyScaling
			{
				get
				{
					return 1.0;
				}
			}

			public override double TemperatureScaling
			{
				get
				{
					return 1.0;
				}
			}
		}

		[Serializable]
		private class InternationalSystemUnitSystem : UnitSystem
		{
			public override double LengthScaling
			{
				get
				{
					// m per Å.
					return 1.0e-10;
				}
			}

			public override double TimeScaling
			{
				get
				{
					return 1.0;
				}
			}

			public override double EnergyScaling
			{
				get
				{
					// J per eV.
					return 1.60217656535e-19;
				}
			}

			public override double TemperatureScaling
			{
				get
				{
					return 1.0;
				}
			}
		}
	}
}
